package hamaster.jpbc.mgr;

import hamaster.jpbc.IDKey;
import hamaster.jpbc.User;
import hamaster.jpbc.dao.IDKeyDAO;
import hamaster.jpbc.dao.UserDAO;
import hamaster.jpbc.pbc.PBCDriver;
import hamaster.jpbc.pbs.PBS;
import hamaster.jpbc.pbs.Signature;
import hamaster.jpbc.sys.IBCSystem;
import hamaster.jpbc.util.Hash;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * 处理客户端的请求
 * @author <a href="mailto:wangyeee@gmail.com">Wang Ye</a>
 */
public class ClientRequestManager implements ManagerConstraint {

	protected IDKeyDAO dao;

	protected UserDAO userDAO;

	public ClientRequestManager() {
	}

	public Properties processRequest(Properties request) {
		String action = request.getProperty("action");
		try {
			Method service = getClass().getMethod(action, Properties.class);
			Properties response = (Properties) service.invoke(this, request);
			return response;
		} catch (SecurityException e) {
			// TODO handle exceptions
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return request;
	}

	public Properties downloadID(Properties request) {
		Properties response = new Properties();
		String email = request.getProperty("email");
		String pwd = request.getProperty("password");
		if (email == null || email.length() < 1) {
			response.setProperty("errormsg", "请输入电子邮件");
			response.setProperty("errorcode", "1");
			return response;
		}
		if (!email.matches("\\w+(\\.\\w+)*@\\w+(\\.\\w+)+")) {
			response.setProperty("errormsg", "请输入合法的电子邮件");
			response.setProperty("errorcode", "2");
			return response;
		}
		if (pwd == null || pwd.length() < 5) {
			response.setProperty("errormsg", "请输入密码");
			response.setProperty("errorcode", "3");
			return response;
		}
		User user = userDAO.login(email, pwd);
		if (user == null) {
			response.setProperty("errormsg", "电子邮件和密码不匹配");
			response.setProperty("errorcode", "4");
			return response;
		}
		IDKey id = dao.get(user);
		// TODO 解密ID内容
		byte[] keyRaw = id.getKeyContent();
		ByteArrayInputStream in = new ByteArrayInputStream(keyRaw);
		Properties p = new Properties();
		try {
			p.load(in);
		} catch (IOException e) {}
		String idKey = Hash.propertiesToHexString(p);
		// 对服务器响应进行数字签名
		byte[] sha1 = Hash.sha1(idKey);
		PBS pbs = PBS.instance();
		Signature sign = pbs.sign(IBCSystem.signatureParameter(), IBCSystem.systemSignatureKey(), sha1);
		ByteArrayOutputStream bout = new ByteArrayOutputStream();
		ByteArrayOutputStream sout = new ByteArrayOutputStream();
		try {
			sign.toProperties(null).store(bout, null);
			IBCSystem.signatureParameter().toProperties(null).store(sout, new String());
		} catch (IOException e) {
			e.printStackTrace();
		}
		response.setProperty("idkey", idKey);
		response.setProperty("idsign", PBCDriver.hex(bout.toByteArray()));
		response.setProperty("serverparams", PBCDriver.hex(sout.toByteArray()));
		response.setProperty("idsignmethod", "sha1");
		response.setProperty("errorcode", "0");
		return response;
	}

	public void setDao(IDKeyDAO dao) {
		this.dao = dao;
	}

	public void setUserDAO(UserDAO userDAO) {
		this.userDAO = userDAO;
	}
}
